#include <stdlib.h>
#include <string.h>
#include <sys/cdefs.h>
#include "esp_compiler.h"
#include "esp_log.h"
#include "driver/pcnt.h"
#include "hal/pcnt_hal.h"
#include "port_encoder.h"
#include "rotary_encoder.h"
#include "port_config.h"

#define ENCODER_MAX_NUM (2)
#define IS_ENCODER_CH(ch) ((ch) < ENCODER_MAX_NUM)
rotary_encoder_t *encoder[ENCODER_MAX_NUM] = {0};

void encoder_init(void)
{
    uint32_t pcnt_unit = 0;
    // Create rotary encoder instance
    pcnt_unit = PCNT_UNIT_0;
    rotary_encoder_config_t config_0 = ROTARY_ENCODER_DEFAULT_CONFIG((rotary_encoder_dev_t)pcnt_unit, GPIO_ENCODER_0_A, GPIO_ENCODER_0_B);
    ESP_ERROR_CHECK(rotary_encoder_new_ec11(&config_0, &encoder[0]));

    // Create rotary encoder instance
    pcnt_unit = PCNT_UNIT_1;
    rotary_encoder_config_t config_1 = ROTARY_ENCODER_DEFAULT_CONFIG((rotary_encoder_dev_t)pcnt_unit, GPIO_ENCODER_1_A, GPIO_ENCODER_1_B);
    ESP_ERROR_CHECK(rotary_encoder_new_ec11(&config_1, &encoder[1]));

    // Filter out glitch (1us)
    ESP_ERROR_CHECK(encoder[0]->set_glitch_filter(encoder[0], 1));
    ESP_ERROR_CHECK(encoder[1]->set_glitch_filter(encoder[1], 1));

    // Start encoder
    ESP_ERROR_CHECK(encoder[0]->start(encoder[0]));
    ESP_ERROR_CHECK(encoder[1]->start(encoder[1]));
}


int encoder_get_counter(uint8_t ch)
{
    if(IS_ENCODER_CH(ch))
    {
        return encoder[ch]->get_counter_value(encoder[ch]);
    }
    return 0;
}

void encoder_clear(uint8_t ch)
{
    if(IS_ENCODER_CH(ch))
    {
        ESP_ERROR_CHECK(encoder[ch]->clear(encoder[ch]));
    }
}